#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_nvic.h"
#include "stm32f10x_rcc.h"

#include "global_conf.h"
#include "bluetooth.h"
#include "stm32f10x_it.h"

static event_callback_t blue_callback;
static void uart_int(void);
static void uart_int(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Clock */
    RCC_APB2PeriphClockCmd(BLUE_GPIO_RCC, ENABLE);
    RCC_APB1PeriphClockCmd(BLUE_UART_RCC, ENABLE);
    /* GPIO */
    /* Configure Rx as input floating */
    GPIO_InitStructure.GPIO_Pin = BLUE_RX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(BLUE_GPIO, &GPIO_InitStructure);
    /* Configure Tx as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = BLUE_TX_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(BLUE_GPIO, &GPIO_InitStructure);
    /* UART */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(BLUE_UART, &USART_InitStructure);
    USART_ITConfig(BLUE_UART, USART_IT_RXNE, ENABLE);
    USART_ITConfig(BLUE_UART, USART_IT_TXE, ENABLE);


    /* Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = BLUE_UART_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    USART_Cmd(BLUE_UART, ENABLE);
}

void bluetooth_isr_handler(void)
{
    u16 temp;
    if (USART_GetITStatus(BLUE_UART, USART_IT_RXNE) != RESET) {
        /* Read one byte from the receive data register */
        temp = USART_ReceiveData(BLUE_UART);
        blue_callback(BLUETOOTH, &temp);
        USART_ClearITPendingBit(BLUE_UART, USART_IT_RXNE);
    }
    if (USART_GetITStatus(BLUE_UART, USART_IT_TXE) != RESET) {
        /* Write one byte to the transmit data register */
        USART_SendData(BLUE_UART, temp);
        blue_callback(BLUETOOTH, &temp);
        USART_ClearITPendingBit(BLUE_UART, USART_IT_TXE);
    }
}
/*============================================================================*/
/* APIs */

void bluetooth_open( struct xbluetooth * blue )
{
    uart_int();
    blue_callback = blue->callback;
}

unsigned long bluetooth_read(unsigned char *buffer)
{
    unsigned long count = 0;
    return count;
}

unsigned long bluetooth_write(unsigned char *buffer)
{
    unsigned long count = 0;
    return count;
}

void bluetooth_register_callback(event_callback_t callback)
{
    blue_callback = callback;
}

void bluetooth_set_baudrate(unsigned long baudrate)
{
    USART_InitTypeDef USART_InitStructure;
    USART_Cmd(BLUE_UART, DISABLE);
    USART_InitStructure.USART_BaudRate = baudrate;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(BLUE_UART, &USART_InitStructure);
    USART_ITConfig(BLUE_UART, USART_IT_RXNE, ENABLE);
    USART_ITConfig(BLUE_UART, USART_IT_TXE, ENABLE);
    USART_Cmd(BLUE_UART, ENABLE);
}

void bluetooth_close( struct xbluetooth * blue )
{
}